#include "trajectory.h"
#include "ui_trajectory.h"
#include <QDebug>

trajectory::trajectory(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::trajectory)
{
    ui->setupUi(this);
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB18030"));
    setupPlot();
    connect(ui->pushButtonAdd,SIGNAL(clicked(bool)),this,SLOT(addPoint()));
    connect(ui->pushButtonHome,SIGNAL(clicked(bool)),this,SLOT(setHome()));
    connect(ui->pushButtonClear,SIGNAL(clicked(bool)),this,SLOT(clearPoint()));
    connect(ui->pushButtonOk,SIGNAL(clicked(bool)),this,SLOT(sendPoint()));
}

trajectory::~trajectory()
{
    delete ui;
}

void trajectory::setupPlot(){
    ui->customPlot->axisRect()->setupFullAxesBox(true);
    ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    ui->customPlot->yAxis->grid()->setSubGridVisible(true);
    ui->customPlot->xAxis->grid()->setSubGridVisible(true);
    ui->customPlot->xAxis->setScaleType(QCPAxis::stLinear);
    ui->customPlot->yAxis->setScaleType(QCPAxis::stLinear);
    ui->customPlot->xAxis->setRange(-10, 10);
    ui->customPlot->yAxis->setRange(-10, 10);

    QAction *actHome = new QAction("set as home");
    QAction *actAdd = new QAction("add point");
    QAction *actRemove = new QAction("remove point");
    QAction *actFix = new QAction("fix point");
    ui->customPlot->addAction(actHome);
    ui->customPlot->addAction(actAdd);
    ui->customPlot->addAction(actRemove);
    ui->customPlot->addAction(actFix);
    ui->customPlot->setContextMenuPolicy(Qt::ActionsContextMenu);
    connect(actHome,SIGNAL(triggered(bool)),this,SLOT(setPointAsHome()));
    connect(actAdd,SIGNAL(triggered(bool)),this,SLOT(addCurPoint()));
    connect(actRemove,SIGNAL(triggered(bool)),this,SLOT(removePoint()));
    connect(actFix,SIGNAL(triggered(bool)),this,SLOT(fixPoint()));
    connect(ui->customPlot,SIGNAL(mouseMove(QMouseEvent*)),this,SLOT(mouseDisplay(QMouseEvent*)));

    home.first=0;home.second=0;
    ui->customPlot->addGraph();
    ui->customPlot->graph(0)->setPen(QPen(Qt::yellow));
    ui->customPlot->graph(0)->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssTriangle, 15));
    ui->customPlot->graph(0)->addData(home.first,home.second);

    graphTrail = new QCPCurve(ui->customPlot->xAxis, ui->customPlot->yAxis);
    graphTrail->data()->set(trail, true);
    graphTrail->setPen(QPen(Qt::green));
    graphTrail->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssStar, 8));

    graphTarget = new QCPCurve(ui->customPlot->xAxis, ui->customPlot->yAxis);
    graphTarget->data()->set(target, true);
    graphTarget->setPen(QPen(Qt::red));
    graphTarget->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 8));

    ui->textEdit->setFont(QFont("Timer" , 8));
    ui->customPlot->replot();
}

void trajectory::mouseDisplay(QMouseEvent* event){
    x_pos = ui->customPlot->xAxis->pixelToCoord(event->pos().x());
    y_pos = ui->customPlot->yAxis->pixelToCoord(event->pos().y());
    QString str = QString("(%1,%2)") .arg(x_pos) .arg(y_pos);
    ui->labelStatus->setText(str);
}

void trajectory::sendPoint(){
    QString str = "no point exist";
    if(!target.empty()){
        send.clear();
        str = QString("send %1 point(s):") .arg(target.size()+1);
        send.push_back(home);
        str += QString("\r\n home:(%1,%2)") .arg(home.first) .arg(home.second);
        for(int i=0;i<target.size();i++){
            str += QString("\r\n     (%1,%2)") .arg(target[i].key) .arg(target[i].value);
            send.push_back(make_pair(target[i].key,target[i].value));
        }
        emit sendData(send);
    }
    ui->textEdit->append(str);
}

void trajectory::addCurPoint(void){
    target.push_back(QCPCurveData(target.size(), x_pos, y_pos));
    graphTarget->data()->set(target, true);
    ui->customPlot->replot();
    QString str = QString("add point:(%1,%2)") .arg(x_pos) .arg(y_pos);
    ui->textEdit->append(str);
}

void trajectory::clearPoint(void){
    target.clear();
    graphTarget->data()->set(target, true);
    ui->customPlot->replot();
    ui->textEdit->append("clear all points");
}

void trajectory::RecvPoint(double x,double y){
    trail.push_back(QCPCurveData(trail.size(), x, y));
    graphTrail->data()->set(trail, true);
    ui->customPlot->replot();
}

void trajectory::addPoint(void){
    QString str = "no add point";
    QString text = QInputDialog::getText(this,tr("add point"),tr("enter point:x,y"));
    if (!text.isEmpty()){
        QStringList list = text.split(',');
        if(list.size()<2)
            str = "illegal input";
        else{
            double x = list.at(0).toDouble();
            double y = list.at(1).toDouble();
            target.push_back(QCPCurveData(target.size(), x, y));
            str = QString("add point:(%1,%2)") .arg(x) .arg(y);
            graphTarget->data()->set(target, true);
            ui->customPlot->replot();
        }
    }
    ui->textEdit->append(str);
}

void trajectory::removePoint(void){
    double offset=ui->customPlot->xAxis->range().size()/50;
    QString str = "no point select";
    bool selectflag = false;
    for(auto iter = target.begin();iter != target.end();iter++){
        if(qAbs(iter->key-x_pos)<offset && qAbs(iter->value-y_pos)<offset){
            target.erase(iter);
            str = QString("remove point:(%1,%2)") .arg(iter->key) .arg(iter->value);
            selectflag = true;
            break;
        }
    }
    if(selectflag){
        for(int i=0;i<target.size();i++)
           target[i].t = i;
        graphTarget->data()->set(target, true);
        ui->customPlot->replot();
    }
    ui->textEdit->append(str);
}

void trajectory::setHome(void){
    QString str = QString("set home:(%1,%2)") .arg(home.first) .arg(home.second);
    ui->customPlot->graph(0)->data()->clear();
    ui->customPlot->graph(0)->addData(home.first,home.second);
    ui->customPlot->replot();
    ui->textEdit->append(str);
}

void trajectory::setPointAsHome(void){
    home.first = x_pos;
    home.second = y_pos;
    setHome();
}

void trajectory::fixPoint(void){
    double offset=ui->customPlot->xAxis->range().size()/50;
    QString str = "no point select";
    int index = -1;
    for(int i=0;i<target.size();i++){
        if(qAbs(target[i].key-x_pos)<offset && qAbs(target[i].value-y_pos)<offset){
            str = QString("fix point:(%1,%2)") .arg(target[i].key) .arg(target[i].value);
            index = i;
            break;
        }
    }
    if(index!=-1){
        QString text = QInputDialog::getText(this,tr("fix point"),tr("enter point:x,y"));
        if (!text.isEmpty()){
            QStringList list = text.split(',');
            if(list.size()<2)
                str = "illegal input";
            else{
                target[index].key = list.at(0).toDouble();
                target[index].value = list.at(1).toDouble();
                str += "\r\n" + QString("----point:(%1,%2)") .arg(target[index].key) .arg(target[index].value);
                graphTarget->data()->set(target, true);
                ui->customPlot->replot();
            }
        }
        else str = "cancel fix point";
        graphTarget->data()->set(target, true);
        ui->customPlot->replot();
    }
    else{
        if(qAbs(home.first-x_pos)<offset && qAbs(home.second-y_pos)<offset){
            QString text = QInputDialog::getText(this,tr("fix point"),tr("enter point:x,y"));
            if (!text.isEmpty()){
                QStringList list = text.split(',');
                if(list.size()<2)
                    str = "illegal input";
                else{
                    home.first  = list.at(0).toDouble();
                    home.second = list.at(1).toDouble();
                    setHome();
                    return;
                }
            }
            else str = "cancel fix point";
        }
    }
    ui->textEdit->append(str);
}
